/**
 * <p>Copyright (c) 2011 深圳市鹏途信息技术有限公司 </p>
 * <p>				   All right reserved. 		     </p>
 * 
 * <p>项目名称 ： 	东莞交通工程质量监督综合业务系统        </p>
 * <p>创建者   :	liuyang 
 * 
 * <p>描   述  :   ProcessCustomAssignment.java for com.pengtu.service.custom    </p>
 * 
 * <p>最后修改 : $: 2011-8-17-上午10:32:00 v 1.0.0	 liuyang   $     </p>
 * 
 */

package com.pengtu.service.custom;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.jbpm.api.Configuration;
import org.jbpm.api.Execution;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.TaskService;
import org.jbpm.api.model.OpenExecution;
import org.jbpm.api.task.Assignable;
import org.jbpm.api.task.AssignmentHandler;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.history.HistoryEvent;
import org.jbpm.pvm.internal.history.events.TaskActivityStart;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.task.OpenTask;
import org.jbpm.pvm.internal.task.TaskImpl;

import com.pengtu.service.custom.impl.AllAgreeSign;
import com.pengtu.service.custom.impl.CountersignInfoDefaultImpl;

/**
 * 流程自定义任务节点帮助类
 * 
 * ProcessCustomAssignment
 * 
 * 2011-8-17 上午10:32:00
 * 
 * @version 1.0.0
 * 
 */
public class ProcessCustomAssignment implements AssignmentHandler {

	/**
	 * serialVersionUID:TODO
	 * 
	 * @since 1.0.0
	 */

	private static final long serialVersionUID = 1L;

	private CountersignCalculator countersignCalculator = new AllAgreeSign();

	/**
	 * 获取流程引擎
	 */
	private static final ProcessEngine processEngine = Configuration
			.getProcessEngine();

	/**
	 * 任务服务
	 */
	private static final TaskService taskService = processEngine
			.getTaskService();

	private static final ExecutionService executionService = processEngine
			.getExecutionService();

	private List<String> participants;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.jbpm.api.task.AssignmentHandler#assign(org.jbpm.api.task.Assignable,
	 * org.jbpm.api.model.OpenExecution)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void assign(Assignable assignable, OpenExecution execution)
			throws Exception {
		// TODO Auto-generated method stub

		String pid = execution.getProcessInstance().getId();
		// participants = (List<String>) execution.getVariable("participants");
		// 获取主任务
		Task task = taskService.createTaskQuery().processInstanceId(pid)
				.activityName(execution.getName()).uniqueResult();

		// 获取会签参与人
		participants = (List<String>) taskService.getVariable(task.getId(),
				"participants");

		createSubTask(task);

		String leader = (String) taskService
				.getVariable(task.getId(), "leader");
		List<String> list = new ArrayList<String>();
		for (String str : participants) {
			if (!(StringUtils.equals(leader, str))) {
				list.add(str);
			}
		}

		CountersignInfo countersignInfo = new CountersignInfoDefaultImpl(
				list, countersignCalculator);

		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("parentTaskId", task.getId());
		vars.put("countersignInfo", countersignInfo);

		taskService.setVariables(task.getId(), vars);
	}

	/**
	 * 创建子任务
	 * 
	 * @param task
	 */
	private void createSubTask(Task task) {
		Execution execution = executionService.findExecutionById(task
				.getExecutionId());
		if (participants != null) {
			for (String participant : participants) {
				// 创建子流程
				TaskImpl subTask = (TaskImpl) ((OpenTask) task).createSubTask();

				// 设置会签参与者为子任务的分配者
				subTask.setAssignee(participant);
				subTask.setName(task.getName());
				subTask.setExecution((ExecutionImpl) execution);
				subTask.setSuperTask((TaskImpl) task);

				// 关联主任务
				taskService.addTaskParticipatingUser(task.getId(), participant,
						Participation.CLIENT);

				HistoryEvent.fire(new TaskActivityStart((TaskImpl) subTask),
						(ExecutionImpl) execution);
			}
		}
	}

}
